package june.asynchronoustest;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.http.AndroidHttpClient;



public class DownloadBitmap {
	
	public enum Mode { NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT }
    private Mode mode = Mode.NO_ASYNC_TASK;
	

	public Bitmap downloadBitmap(String strImageURL) 
    {
        final HttpClient client			= (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() : AndroidHttpClient.newInstance("Android");
        final HttpGet getRequest 		= new HttpGet(strImageURL);
        final int IMAGE_MAX_SIZE 		= 1280;
        
        try 
        {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();
            
            if (statusCode != HttpStatus.SC_OK) 
            {
                return null;
            }

            final HttpEntity entity = response.getEntity();
            
            if (entity != null) 
            {
                InputStream inputStream = null;
                
                try 
                {
                	inputStream = entity.getContent();
                	
                	BitmapFactory.Options bfo 	= new BitmapFactory.Options();
                	bfo.inJustDecodeBounds 		= true;

                    BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, bfo);
                    
                    if(bfo.outHeight * bfo.outWidth >= IMAGE_MAX_SIZE * IMAGE_MAX_SIZE)
                    {
                    	bfo.inSampleSize = (int)Math.pow(2, (int)Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(bfo.outHeight, bfo.outWidth)) / Math.log(0.5)));
                    }
                    bfo.inJustDecodeBounds = false;
                    
                    response = client.execute(getRequest);
                    final int nRetryStatusCode = response.getStatusLine().getStatusCode();
                    
                    if (nRetryStatusCode != HttpStatus.SC_OK) 
                    {
                        return null;
                    }
                    
                    final HttpEntity reEntity = response.getEntity();
                    
                    if (reEntity != null)
                    {
                    	InputStream reInputStream = null;
                    	
                    	try
                    	{
                    		reInputStream = reEntity.getContent();
                    		final Bitmap imgBitmap = BitmapFactory.decodeStream(new FlushedInputStream(reInputStream), null, bfo);
                            
                            return imgBitmap;
                    	}
                    	finally 
                        {
                    		 if (reInputStream != null) 
                             {
                    			 reInputStream.close();
                             }
                    		 
                    		 reEntity.consumeContent();
                        }
                    }
                } 
                finally 
                {
                    if (inputStream != null) 
                    {
                        inputStream.close();
                    }
                    
                    entity.consumeContent();
                }
            }
        } 
        catch (IOException e) 
        {
            getRequest.abort();
        } 
        catch (IllegalStateException e) 
        {
            getRequest.abort();
        } 
        catch (Exception e) 
        {
            getRequest.abort();
        } 
        finally 
        {
            if ((client instanceof AndroidHttpClient)) 
            {
                ((AndroidHttpClient)client).close();
            }
        }
        
        return null;
        
    }
	
	class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

}
